//
// Created by SDSC\202100300261 on 23-11-13.
//

#include "TABLE.h"
#include "MyException.h"

TABLE::TABLE() {
    TX = 0;
//    DX = 3;//0,1,2分别为SL,DL,RA
    DX.push(3);//DX从
    LEVEL = 0;

//    table = new std::vector<TABLE_ENTRY>();
}
TABLE_ENTRY::TABLE_ENTRY() {}
TABLE_ENTRY::TABLE_ENTRY(
        std::string _name,SYMS _kind,int _value,int _level,int _adr
){
name = _name;
kind = _kind;
value = _value;
level = _level;
adr = _adr;
}
void TABLE::check(const TABLE_ENTRY *entry) {
//    for(auto i : table) {
//        if(i==(*entry)) {
//            throw MyException("redefined name " + i.name +  "\nfirst appeared as " + nameSym(i.kind) + "\nappeared again as " +
//                              nameSym(entry -> kind) );
//        }
//    }
}

/*
 * 添加一个Const变量，const变量的level为0
 */
void TABLE::addConst(const std::string &name, int value) {
//    checkName(name,SYMS::CONST);
    auto *tmp = new TABLE_ENTRY(name,SYMS::CONST,value,0,0);
    check(tmp);
    table.push_back(*tmp);
    TX++;
}
void TABLE::addVar(const std::string &name) {
    auto *tmp = new TABLE_ENTRY(name,SYMS::VAR,0,LEVEL,DX.top());
    check(tmp);
    table.push_back(*tmp);
    DX.top()++;
    TX++;
}

//开始一个过程
int TABLE::addPro(const std::string &name) {
    auto *tmp = new TABLE_ENTRY(name,SYMS::PROCEDURE,0,LEVEL,0);
    check(tmp);
    table.push_back(*tmp);
    TX++;
    LEVEL++;
    DX.push(3);
    return TX - 1;
}
void TABLE::setPro(int index, int adr) {
    table[index].adr = adr;
}
//结束一个过程
void TABLE::killPro() {
    LEVEL--;
    DX.pop();
}

bool operator == (const TABLE_ENTRY& a,const TABLE_ENTRY& b) {
    return a.name == b.name && a.level == b.level;
}

TABLE_ENTRY* TABLE::getEntry(const std::string &name) {
    for (auto i: table)
        if (i.name == name) {
//            std::cout<<i<<std::endl;
            return new TABLE_ENTRY(i.name,i.kind,i.value,i.level,i.adr);
        }
//            std::cout<<"get it"<<std::endl;
    return nullptr;
}

std::ostream& operator<<(std::ostream& os,const TABLE& obj) {
    for(auto i : obj.table) {
        os << i << std::endl;
    }
}

std::ostream& operator<<(std::ostream& os,const TABLE_ENTRY& obj) {
    os <<std::left<<"name:"<<std::setw(10)<< obj.name << " kind:"<<std::setw(10)
    << nameSym(obj.kind) << " value:" <<std::setw(10)<< obj.value << " level:"
    <<std::setw(10)<< obj.level << " adr:"<<std::setw(10) << obj.adr;
    return os;
}